package com.ray.base.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ray.base.builder.CustomerBuilder;
import com.ray.base.builder.CustomerPrintBuilder;
import com.ray.base.builder.PropBuilder;
import com.ray.base.builder.TemplateExtendBuilder;
import com.ray.base.check.CustomerCheck;
import com.ray.base.enums.CustomerTypeEnum;
import com.ray.base.enums.TemplateTypeEnum;
import com.ray.base.service.BaseCustomerPrintService;
import com.ray.base.service.BaseCustomerService;
import com.ray.base.service.BaseTemplateExtendService;
import com.ray.base.service.BaseTemplateService;
import com.ray.base.table.dto.CustomerQueryDTO;
import com.ray.base.table.entity.BaseCustomer;
import com.ray.base.table.entity.BaseCustomerPrint;
import com.ray.base.table.entity.BaseTemplateExtend;
import com.ray.base.table.params.customer.CustomerCreateParams;
import com.ray.base.table.params.customer.CustomerEditParams;
import com.ray.base.table.params.customer.CustomerPrintSaveParams;
import com.ray.base.table.params.customer.CustomerQueryParams;
import com.ray.base.table.vo.customer.CustomerPrintVO;
import com.ray.base.table.vo.customer.CustomerVO;
import com.ray.base.table.vo.material.PropVO;
import com.ray.common.check.AbstractCheck;
import com.ray.system.builder.CommonPageBuilder;
import com.ray.validate.support.utils.ValidateUtil;
import com.ray.woodencreate.annotation.ServiceLog;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.enums.YesOrNoEnum;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.page.CommonPage;
import com.ray.woodencreate.result.MsgCodeConstant;
import com.ray.woodencreate.result.Result;
import com.ray.woodencreate.result.ResultFactory;
import com.ray.woodencreate.util.Assert;
import com.ray.woodencreate.util.LogInUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 客户相关服务
 * @Class: CustomerApi
 * @Package com.ray.base.api
 * @date 2020/5/27 11:15
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Service
@Slf4j
public class CustomerApi {

    @Autowired
    private BaseCustomerService baseCustomerService;
    @Autowired
    private BaseCustomerPrintService customerPrintService;
    @Autowired
    private BaseTemplateService baseTemplateService;
    @Autowired
    private BaseTemplateExtendService baseTemplateExtendService;



    /**
     * 客户查询-分页
     * @param queryParams
     * @return
     */
    @ServiceLog(name = "客户查询-分页")
    public Result<IPage<CustomerVO>> pageCustomers(CommonPage<CustomerQueryParams, Page<CustomerVO>> queryParams) {
        Assert.notNull(queryParams, "参数[queryParams]不存在");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CommonPageBuilder<CustomerQueryDTO, BaseCustomer> commonPageBuilder = new CommonPageBuilder<>(CustomerQueryDTO.class);
        commonPageBuilder.appendEntity(queryParams.getEntity()).appendQuery(queryParams.getQuery()).appendPage(queryParams.getPage());
        IPage<BaseCustomer> page = baseCustomerService.page(commonPageBuilder.bulid(), loginUser);
        List<BaseCustomer> customers = page.getRecords();
        //结果对象
        IPage<CustomerVO> pageList = new Page<>();
        pageList.setTotal(page.getTotal());
        pageList.setCurrent(page.getCurrent());
        pageList.setSize(page.getSize());
        //查询到结果 数据转换
        if (ObjectUtil.isNotNull(customers)) {
            pageList.setRecords(customers.stream().map(sysCustomer -> {
                CustomerVO customerVO = new CustomerVO();
                BeanUtil.copyProperties(sysCustomer, customerVO);
                return customerVO;
            }).collect(Collectors.toList()));
        } else {
            pageList.setRecords(new ArrayList<>());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, pageList);
    }

    /**
     * 客户列表查询
     *
     * @param queryParams
     * @return
     */
    @ServiceLog(name = "客户列表查询")
    public Result<List<CustomerVO>> queryCustomers(CustomerQueryParams queryParams) {
        Assert.notNull(queryParams, "参数[queryParams]不存在");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CustomerQueryDTO queryDTO = new CustomerQueryDTO();
        BeanUtil.copyProperties(queryParams, queryDTO);
        queryDTO.setStatus(YesOrNoEnum.YES.getValue());
        List<BaseCustomer> customers = baseCustomerService.list(queryDTO, loginUser);
        //查询对象
        List<CustomerVO> list = new ArrayList<>();
        if (ObjectUtil.isNotNull(customers)) {
            list = customers.stream().map(sysCustomer -> {
                CustomerVO customerVO = new CustomerVO();
                BeanUtil.copyProperties(sysCustomer, customerVO);
                return customerVO;
            }).collect(Collectors.toList());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, list);
    }


    /**
     * 创建客户
     *
     * @param createParams 创建对象
     * @return Result
     */
    @Transactional
    @ServiceLog(name = "创建客户")
    public Result<String> createCustomer(CustomerCreateParams createParams) {
        ValidateUtil.validate(createParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        CustomerTypeEnum customerTypeEnum = CustomerTypeEnum.getEnum(createParams.getCustomerType());
        new AbstractCheck<>(customerTypeEnum).checkNull("客户类型错误");
        BaseCustomer baseCustomer = baseCustomerService.queryCustomerByCustomerName(createParams.getCustomerName(), createParams.getCustomerType(),loginUser);
        new CustomerCheck(baseCustomer).checkSam(null, "客户名称已经存在");
        CustomerBuilder customerBuilder = new CustomerBuilder();
        customerBuilder.append(createParams).appendStatus(YesOrNoEnum.YES.getValue()).appendCreate(loginUser);
        //保存客户信息
        if (!baseCustomerService.save(customerBuilder.bulid())) {
            log.info("保存客户接口异常,参数:{}", JSON.toJSONString(customerBuilder.bulid()));
            throw BusinessExceptionFactory.newException("保存客户异常");
        }
        //查询信息 需要配置属性
        Map<String, String> tempMap = baseTemplateService.listByComapnyCode(TemplateTypeEnum.CUSTOMER.getValue(), loginUser)
                .stream().collect(Collectors.toMap(item -> item.getProp(), item -> item.getName()));
        List<String> existProp = new ArrayList<>();
        //保存扩展信息
        baseTemplateExtendService.saveBatch(createParams.getProps().stream().map(templateRecord -> {
            TemplateExtendBuilder templateExtendBuilder = new TemplateExtendBuilder();
            String name = tempMap.get(templateRecord.getProp());
            if(StrUtil.isBlank(name)){
                log.info("属性{}不存在",templateRecord.getProp());
                throw BusinessExceptionFactory.newException("属性不存在");
            }
            if(existProp.contains(templateRecord.getProp())){
                log.info("属性{}存在重复",templateRecord.getProp());
                throw BusinessExceptionFactory.newException("属性重复");
            }
            existProp.add(templateRecord.getProp());
            templateExtendBuilder.append(templateRecord).appendCode(customerBuilder.getCode())
                    .appendCompanyCode(loginUser.getCompanyCode()).appendName(name)
                    .appendCreate(loginUser);
            return templateExtendBuilder.bulid();
        }).collect(Collectors.toList()));
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, customerBuilder.getCode());
    }

    /**
     * 编辑客户
     *
     * @param editParams 编辑对象
     * @return Result
     */
    @Transactional
    @ServiceLog(name = "编辑客户")
    public Result<String> editCustomer(CustomerEditParams editParams) {
        ValidateUtil.validate(editParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CustomerBuilder customerBuilder = new CustomerBuilder();
        customerBuilder.append(editParams).appendEdit(loginUser);
        //获取权限信息
        BaseCustomer sysCustomer = baseCustomerService.queryCustomerByCustomerCode(editParams.getCustomerCode(), loginUser);
        new CustomerCheck(sysCustomer).checkNull("客户不存在");
        BaseCustomer baseCustomer = baseCustomerService.queryCustomerByCustomerName(editParams.getCustomerName(), sysCustomer.getCustomerType(),loginUser);
        new CustomerCheck(baseCustomer).checkSam(editParams.getCustomerCode(), "客户名称已经存在");
        //编辑客户信息
        if (!baseCustomerService.edit(customerBuilder.bulid(), loginUser)) {
            log.info("编辑客户接口异常,参数:{}", JSON.toJSONString(customerBuilder.bulid()));
            throw BusinessExceptionFactory.newException("编辑客户异常");
        }
        //删除信息
        baseTemplateExtendService.deleteTemplateExtend(editParams.getCustomerCode(), loginUser);
        //查询信息 需要配置属性
        Map<String, String> tempMap = baseTemplateService.listByComapnyCode(TemplateTypeEnum.CUSTOMER.getValue(), loginUser)
                .stream().collect(Collectors.toMap(item -> item.getProp(), item -> item.getName()));
        List<String> existProp = new ArrayList<>();
        //保存扩展信息
        baseTemplateExtendService.saveBatch(editParams.getProps().stream().map(templateRecord -> {
            TemplateExtendBuilder templateExtendBuilder = new TemplateExtendBuilder();
            String name = tempMap.get(templateRecord.getProp());
            if(StrUtil.isBlank(name)){
                log.info("属性{}不存在",templateRecord.getProp());
                throw BusinessExceptionFactory.newException("属性不存在");
            }
            if(existProp.contains(templateRecord.getProp())){
                log.info("属性{}存在重复",templateRecord.getProp());
                throw BusinessExceptionFactory.newException("属性重复");
            }
            existProp.add(templateRecord.getProp());
            templateExtendBuilder.append(templateRecord).appendCode(customerBuilder.getCode())
                    .appendCompanyCode(loginUser.getCompanyCode()).appendName(name)
                    .appendCreate(loginUser);
            return templateExtendBuilder.bulid();
        }).collect(Collectors.toList()));
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, customerBuilder.getCode());
    }


    /**
     * 删除客户
     *
     * @param customerCode 客户编码
     * @return Result
     */
    @Transactional
    @ServiceLog(name = "删除客户")
    public Result<String> deleteCustomer(String customerCode) {
        ValidateUtil.hasLength(customerCode, "参数[customerCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseCustomer sysCustomer = baseCustomerService.queryCustomerByCustomerCode(customerCode, loginUser);
        new CustomerCheck(sysCustomer).checkNull("客户不存在");
        CustomerBuilder customerBuilder = new CustomerBuilder();
        customerBuilder.appendCode(customerCode).appendEdit(loginUser).delete();
        //删除客户信息
        if (!baseCustomerService.edit(customerBuilder.bulid(), loginUser)) {
            log.info("删除客户接口异常,参数:{}", JSON.toJSONString(customerBuilder.bulid()));
            throw BusinessExceptionFactory.newException("删除客户异常");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, customerBuilder.getCode());
    }

    /**
     * 开启客户
     *
     * @param customerCode 客户编码
     * @return Result
     */
    @Transactional
    @ServiceLog(name = "开启客户")
    public Result<String> openCustomer(String customerCode) {
        ValidateUtil.hasLength(customerCode, "参数[customerCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseCustomer sysCustomer = baseCustomerService.queryCustomerByCustomerCode(customerCode, loginUser);
        new CustomerCheck(sysCustomer).checkNull("客户不存在");
        CustomerBuilder customerBuilder = new CustomerBuilder();
        customerBuilder.appendCode(customerCode).appendEdit(loginUser).open();
        //开启客户信息
        if (!baseCustomerService.edit(customerBuilder.bulid(), loginUser)) {
            log.info("开启客户接口异常,参数:{}", JSON.toJSONString(customerBuilder.bulid()));
            throw BusinessExceptionFactory.newException("开启客户异常");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, customerBuilder.getCode());
    }

    /**
     * 关闭客户
     * @param customerCode 客户编码
     * @return Result
     */
    @Transactional
    @ServiceLog(name = "关闭客户")
    public Result<String> closeCustomer(String customerCode) {
        ValidateUtil.hasLength(customerCode, "参数[customerCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseCustomer sysCustomer = baseCustomerService.queryCustomerByCustomerCode(customerCode, loginUser);
        new CustomerCheck(sysCustomer).checkNull("客户不存在");
        CustomerBuilder customerBuilder = new CustomerBuilder();
        customerBuilder.appendCode(customerCode).appendEdit(loginUser).close();
        //关闭客户信息
        if (!baseCustomerService.edit(customerBuilder.bulid(), loginUser)) {
            log.info("关闭客户接口异常,参数:{}", JSON.toJSONString(customerBuilder.bulid()));
            throw BusinessExceptionFactory.newException("关闭客户异常");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, customerBuilder.getCode());
    }

    /**
     * 客户详情
     *
     * @param customerCode 客户编码
     * @return Result
     */
    @ServiceLog(name = "客户详情")
    public Result<CustomerVO> viewCustomer(String customerCode) {
        ValidateUtil.hasLength(customerCode, "参数[customerCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseCustomer sysCustomer = baseCustomerService.queryCustomerByCustomerCode(customerCode, loginUser);
        new CustomerCheck(sysCustomer).checkNull("客户不存在");
        CustomerVO customerVO = new CustomerVO();
        BeanUtil.copyProperties(sysCustomer, customerVO);
        //获取扩展信息
        Map<String, BaseTemplateExtend> extendMap = baseTemplateExtendService.listByObjectCode(customerCode).stream()
                .collect(Collectors.toMap(item -> item.getProp(), item -> item));
        //获取属性信息
        List<PropVO> propVOS = baseTemplateService.listByComapnyCode(TemplateTypeEnum.CUSTOMER.getValue(),loginUser).stream().map(baseTemplate -> {
            return new PropBuilder().append(baseTemplate).append(extendMap.get(baseTemplate.getProp())).bulid();
        }).collect(Collectors.toList());
        customerVO.setProps(propVOS);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, customerVO);
    }


    /**
     * 保存客户打印信息
     *
     * @param editParams 编辑对象
     * @return Result
     */
    @Transactional
    @ServiceLog(name = "保存客户打印信息")
    public Result<String> saveCustomerPrint(CustomerPrintSaveParams editParams) {
        ValidateUtil.validate(editParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CustomerPrintBuilder customerBuilder = new CustomerPrintBuilder();
        customerBuilder.append(editParams);
        //获取权限信息
       // BaseCustomer sysCustomer = baseCustomerService.queryCustomerByCustomerCode(editParams.getCustomerCode(), loginUser);
        //new CustomerCheck(sysCustomer).checkNull("客户不存在");
        //查询
        BaseCustomerPrint customerPrint = customerPrintService.queryCustomerByCustomerCode(editParams.getCustomerCode(), loginUser);
        if(ObjectUtil.isNull(customerPrint)){
            customerBuilder.appendCreate(loginUser);
            customerPrintService.save(customerBuilder.bulid());
        }else {
            //编辑客户信息
            customerBuilder.appendEdit(loginUser);
            if (!customerPrintService.edit(customerBuilder.bulid(), loginUser)) {
                log.info("编辑客户接口异常,参数:{}", JSON.toJSONString(customerBuilder.bulid()));
                throw BusinessExceptionFactory.newException("编辑客户异常");
            }
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, customerBuilder.getCode());
    }

    /**
     * 客户打印信息详情
     *
     * @param customerCode 客户编码
     * @return Result
     */
    @ServiceLog(name = "客户打印信息详情")
    public Result<CustomerPrintVO> viewCustomerPrint(String customerCode) {
        ValidateUtil.hasLength(customerCode, "参数[customerCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseCustomerPrint customerPrint = customerPrintService.queryCustomerByCustomerCode(customerCode, loginUser);
        CustomerPrintVO customerVO = new CustomerPrintVO();
        customerVO.setCustomerCode(customerCode);
        if(ObjectUtil.isNotNull(customerPrint)){
            customerVO.setTemplate(customerPrint.getTemplate());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, customerVO);
    }

}
